// File: MathFunctions.cpp
// Name: Samuel Brush
// Date: 3/26/2014
// Course: CS 325 - Software Development
// Desc: Function implementations that calculate mean, standard deviations, kurtosis, and skewness for a
//       set of numbers.
// Usage: Put doubles into a vector, then pass into the functions. Return value is answer.
//			Use with MathFunctions.h and a driver.

#include "MathFunctions.h"
#include <vector>
#include <cmath>
using namespace std;

//returns the mean, or average, of the values contained in the vector "values"
double mean(const vector<double> &values) {
	if (values.size() == 0) {
		return DIVIDE_BY_ZERO;
	}
	double total = 0;
	for (unsigned int i = 0; i < values.size(); ++i) {
		total += values[i];
	}
	return total / values.size();
}

//returns the standard deviation of the values contained in the vector "values"
double stdev(const vector<double> &values) {
	if (values.size() == 0) {
		return DIVIDE_BY_ZERO;
	}
	double avg = mean(values);
	double deviation_squared_total = 0;
	for (unsigned int i = 0; i < values.size(); ++i) {
		deviation_squared_total += pow(values[i] - avg, 2);
	}
	return sqrt(deviation_squared_total / values.size());
}

//returns the kurtosis of the values contained in the vector "values"
double kurtosis(const vector<double> &values) {
	if (values.size() <= 1) {
		return DIVIDE_BY_ZERO;
	}
	double avg = mean(values);
	double numerator_sum = 0;
	for (unsigned int i = 0; i < values.size(); ++i) {
		numerator_sum += pow(values[i] - avg, 4);
	}
	double numerator = numerator_sum / values.size();
	double denominator_sum = 0;
	for (unsigned int i = 0; i < values.size(); ++i) {
		denominator_sum += pow(values[i] - avg, 2);
	}
	double denominator = pow(denominator_sum / values.size(), 2);
	return numerator / denominator - 3;
}

//returns the skewness of the values contained in the vector "values"
double skewness(const vector<double> &values) {
	if (values.size() <= 1) {
		return DIVIDE_BY_ZERO;
	}
	double avg = mean(values);
	double numerator_sum = 0;
	for (unsigned int i = 0; i < values.size(); ++i) {
		numerator_sum += pow(values[i] - avg, 3);
	}
	double numerator = numerator_sum / values.size();
	double denominator_sum = 0;
	for (unsigned int i = 0; i < values.size(); ++i) {
		denominator_sum += pow(values[i] - avg, 2);
	}
	double denominator = pow(denominator_sum / values.size(), 3/2);
	return numerator / denominator;
}